package com.opdar.seed.idoc.controllers;

import com.opdar.framework.web.SeedWeb;
import com.opdar.framework.web.anotations.Before;
import com.opdar.framework.web.anotations.Controller;
import com.opdar.framework.web.anotations.Inject;
import com.opdar.framework.web.anotations.Router;
import com.opdar.framework.web.interfaces.View;
import com.opdar.seed.extra.utils.*;
import com.opdar.seed.idoc.auth.AuthInterceptor;
import com.opdar.seed.idoc.base.JSONParser;
import com.opdar.seed.idoc.base.MDView;
import com.opdar.seed.idoc.base.TemplateView;
import com.opdar.seed.idoc.base.UrlParser;
import com.opdar.seed.idoc.beans.*;
import com.opdar.seed.idoc.services.InterfaceService;
import com.opdar.seed.idoc.services.ProjectService;
import sun.misc.BASE64Decoder;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;

/**
 * Created by 俊帆 on 2015/8/19.
 */

@Controller(value = "/interface", prefix = "html")
@Before(AuthInterceptor.class)
public class InterfaceController {

    @Inject
    InterfaceService interfaceService;
    @Inject
    ProjectService projectService;
    @Inject
    JSONParser parser;

    @Router("#{projectId}")
    public View project(String projectId){
        ProjectEntity projectEntity = projectService.findById(projectId);
        Map<String,Object> dataModels = new HashMap<String, Object>();
        dataModels.put("projectName",projectEntity.getProjectName());
        List<InterfaceEntity> list = interfaceService.findInterfaceWithProject(projectId);
        dataModels.put("interfaces",list);
        SeedWeb.SharedRequest().get().getSession().setValue("projectId", projectId);
        dataModels.put("projectId",projectId);
        return new TemplateView("interfaces/index.html",dataModels);
    }


    @Router("download")
    public View download(String projectId) {
        ProjectEntity project = projectService.findById(projectId);
        List<InterfaceEntity> list = interfaceService.findInterfaceWithProject(projectId);
        StringBuilder builder = new StringBuilder();
        for(InterfaceEntity entity:list){
            List<ShareVarEntity> vars = projectService.findShareVars(projectId);
            Map<String, Object> result = new HashMap<String, Object>();
            result.put("name",entity.getInterfaceName());
            result.put("id",entity.getId());
            String url = getUrl(entity,vars);
            result.put("url",url);
            result.put("params", getParams(entity));
            BASE64Decoder decoder = new BASE64Decoder();
            try {
                result.put("result",new String(decoder.decodeBuffer(entity.getResult()),"utf-8"));
            } catch (IOException e) {
                e.printStackTrace();
            }
            TemplateView templateView = new TemplateView("interface.md",result);
            byte[] bytes = templateView.renderView();
            try {
                builder.append(new String(bytes,"utf-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return new MDView(builder.toString().getBytes(),project.getProjectName()+".md.zip");
    }

    @Router("create")
    public View create(String id){
        Map<String,Object> dataModel = new HashMap<String, Object>();
        InterfaceEntity entity = null;
        interfaceService.create(id, dataModel);
        return new TemplateView("interfaces/create.html",dataModel);
    }


    @Router("/save")
    public Object save(InterfaceEntity inter){
        InterfaceEntity ifer =interfaceService.save(inter);
        return ifer.getId();
    }

    @Router("/request")
    public Object request(String id){
        InterfaceEntity inter = interfaceService.findById(id);
        List<ShareVarEntity> vars = projectService.findShareVars(inter.getProjectId());
        Map<String, Object> result = executeInterface( inter, vars);
        if(result.containsKey("result") || !StringUtils.isBlank(result.get("result"))){
            return result.get("result");
        }
        return "(empty)";
    }

    private Map<String, Object> executeInterface(InterfaceEntity ifer, List<ShareVarEntity> vars) {
        String url = getUrl(ifer, vars);
        HashMap<String, Object> params = getParams(ifer);
        HashMap<String, Object> headers = getHeaders(ifer);
        Map<String,Object> result = new HashMap<String, Object>();
        result.put("id", ifer.getId());
        try {
            String projectId = SeedWeb.SharedRequest().get().getSession().getValue("projectId").toString();
            ProjectEntity projectEntity = projectService.findById(projectId);
            Class decoderClz = DecoderLoader.getDecoder(projectEntity.getDecoder());
            Decoder decoder = null;
            if(decoderClz != null){
                decoder = (Decoder) decoderClz.newInstance();
            }else{
                decoder = new DefaultDecoder();
            }
            NetUtils.NetResult resultStr = NetUtils.post(url, params, headers, ifer.getBody(),decoder);
            interfaceService.updateResultById(resultStr.getResult(), ifer.getId());
            result.put("code", resultStr.getCode());
            result.put("url",url);
            result.put("params",params);
            result.put("result",resultStr.getResultStr());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    private String getUrl(InterfaceEntity ifer, List<ShareVarEntity> vars) {
        HashMap<String,Object> objectMap = new HashMap<String, Object>();
        for(ShareVarEntity var:vars){
            objectMap.put(var.getKey(),var.getValue());
        }
        String url = UrlParser.get(ifer.getUrl(), objectMap);
        if(!StringUtils.isBlank(ifer.getQueryString())){
            url +="?"+ifer.getQueryString();
        }
        return url;
    }

    private HashMap<String, Object> getHeaders(InterfaceEntity ifer) {
        HashMap<String,Object> headers = new HashMap<String, Object>();
        if(!StringUtils.isBlank(ifer.getHeaders())){
            List<HeaderEntity> headerEntities = parser.parseArray(ifer.getHeaders(),HeaderEntity.class);
            for(HeaderEntity header:headerEntities){
                String key = header.getHeaderKey();
                String value = header.getHeaderValue();
                headers.put(key,value);
            }
        }
        return headers;
    }

    private HashMap<String, Object> getParams(InterfaceEntity ifer) {
        HashMap<String,Object> params = new HashMap<String, Object>();
        if(!StringUtils.isBlank(ifer.getPostParams())){
            List<ParamEntity> paramEntities = parser.parseArray(ifer.getPostParams(),ParamEntity.class);
            for(ParamEntity param:paramEntities){
                String key = param.getParamKey();
                String value = param.getParamValue();
                params.put(key,value);
            }
        }
        return params;
    }

    @Router("/remove")
    public Object remove(String id){
        if(interfaceService.remove(id)){
            return ResultEntity.getSuccess(null);
        }
        return ResultEntity.getFailure(1,"删除失败",null);
    }

}
